/*
 *
 * Copyright 2011 and 2012 University of Illinois
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

var EXPORTED_SYMBOLS = ["OAA_CI_UTILS"];

/**
 * @namespace OAA_CI_UTILS
 */

var OAA_CI_UTILS = {
  result:                null,
  ruleset_nls:           null,
  log:                   null,
  default_toolbarbutton: 'IMAGES_BUTTON',
  default_menuitem:      'ID_MENU_IMAGES',
  last_toolbarbutton_id: null,
  last_node_highlighted: null,
  console_enabled:       true
}

/**
 * @function console
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Display message in browser's console window.
 *
 * @param {String} message - message to display
 */

OAA_CI_UTILS.console = function (message) {
  if (!OAA_CI_UTILS.console_enabled) return;
  var console = Components.classes["@mozilla.org/consoleservice;1"].getService(
                  Components.interfaces.nsIConsoleService);
  console.logStringMessage(message);
};

OAA_CI_UTILS.console("OAA_CI_UTILS loaded");

/**
 * @function getSidebarId
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Get the XUL ID of the sidebar associated with the specified toolbarbutton ID.
 *
 * @param {String} toolbarbutton_id - XUL ID of toolbarbutton
 *
 * @return XUL ID of sidebar or empty string
 */

OAA_CI_UTILS.getSidebarId = function (toolbarbutton_id) {

  switch (toolbarbutton_id) {

  case 'ABBREV_LANG_BUTTON':
    return 'ID_VIEW_SIDEBAR_ABBREV_LANG';
    break;
    
  case 'IMAGES_BUTTON':
    return 'ID_VIEW_SIDEBAR_IMAGES';
    break;

  case 'MEDIA_BUTTON':
    return 'ID_VIEW_SIDEBAR_MEDIA';
    break;

  case 'CONTROLS_BUTTON':
    return 'ID_VIEW_SIDEBAR_CONTROLS';
    break;

  case 'COLOR_CONTRAST_BUTTON':
    return 'ID_VIEW_SIDEBAR_COLOR_CONTRAST';
    break;

  case 'HEADINGS_LANDMARKS_BUTTON':
    return 'ID_VIEW_SIDEBAR_HEADINGS_LANDMARKS';
    break;

  case 'LINKS_BUTTON':
    return 'ID_VIEW_SIDEBAR_LINKS';
    break;

  case 'LISTS_BUTTON':
    return 'ID_VIEW_SIDEBAR_LISTS';
    break;

  case 'TABLES_BUTTON':
    return 'ID_VIEW_SIDEBAR_TABLES';
    break;

  case 'ELEMENTS_BUTTON':
    return 'ID_VIEW_SIDEBAR_ELEMENTS';
    break;

  case 'PREFERENCES_BUTTON':
    return 'ID_VIEW_SIDEBAR_PREFERENCES';
    break;

  default:
    return '';
    break;
  }

};

/**
 * @function getToolbarButtonId
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Get the XUL ID of the toolbar button associated with the specified sidebar ID.
 *
 * @param {String} sidebar_id - XUL ID of sidebar
 *
 * @return XUL ID of toolbar or empty string
 */

OAA_CI_UTILS.getToolbarButtonId = function (sidebar_id) {

  switch (sidebar_id) {

  case 'ID_VIEW_SIDEBAR_IMAGES':
    return 'IMAGES_BUTTON';
    break;

  case 'ID_VIEW_SIDEBAR_MEDIA':
    return 'MEDIA_BUTTON';
    break;

  case 'ID_VIEW_SIDEBAR_CONTROLS':
    return 'CONTROLS_BUTTON';
    break;

  case 'ID_VIEW_SIDEBAR_COLOR_CONTRAST':
    return 'COLOR_CONTRAST_BUTTON';
    break;

  case 'ID_VIEW_SIDEBAR_HEADINGS_LANDMARKS':
    return 'HEADINGS_LANDMARKS_BUTTON';
    break;

  case 'ID_VIEW_SIDEBAR_LINKS':
    return 'LINKS_BUTTON';
    break;

  case 'ID_VIEW_SIDEBAR_LISTS':
    return 'LISTS_BUTTON';
    break;

  case 'ID_VIEW_SIDEBAR_TABLES':
    return 'TABLES_BUTTON';
    break;

  case 'ID_VIEW_SIDEBAR_ABBREV_LANG':
    return 'ABBREV_LANG_BUTTON';
    break;
    
  case 'ID_VIEW_SIDEBAR_ELEMENTS':
    return 'ELEMENTS_BUTTON';
    break;

  case 'ID_VIEW_SIDEBAR_PREFERENCES':
    return 'PREFERENCES_BUTTON';
    break;

  default:
    return '';
    break;
  }

};

/**
 * @function getMenuItemId
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Get the XUL ID of the toolbar button associated with the specified sidebar ID.
 *
 * @param {String} sidebar_id - XUL ID of sidebar
 *
 * @return XUL ID of menu option or empty string
 */

OAA_CI_UTILS.getMenuItemId = function (sidebar_id) {

  switch (sidebar_id) {

  case 'ID_VIEW_SIDEBAR_IMAGES':
    return 'ID_MENU_IMAGES';
    break;

  case 'ID_VIEW_SIDEBAR_MEDIA':
    return 'ID_MENU_MEDIA';
    break;

  case 'ID_VIEW_SIDEBAR_CONTROLS':
    return 'ID_MENU_CONTROLS';
    break;

  case 'ID_VIEW_SIDEBAR_COLOR_CONTRAST':
    return 'ID_MENU_COLOR_CONTRAST';
    break;

  case 'ID_VIEW_SIDEBAR_HEADINGS_LANDMARKS':
    return 'ID_MENU_HEADINGS_LANDMARKS';
    break;

  case 'ID_VIEW_SIDEBAR_LINKS':
    return 'ID_MENU_LINKS';
    break;

  case 'ID_VIEW_SIDEBAR_LISTS':
    return 'ID_MENU_LISTS';
    break;

  case 'ID_VIEW_SIDEBAR_TABLES':
    return 'ID_MENU_TABLES';
    break;

  case 'ID_VIEW_SIDEBAR_ABBREV_LANG':
    return 'ID_MENU_ABBREV_LANG';
    break;
    
  case 'ID_VIEW_SIDEBAR_ELEMENTS':
    return 'ID_MENU_ELEMENTS';
    break;

  case 'ID_VIEW_SIDEBAR_PREFERENCES':
    return 'ID_MENU_PREFERENCES';
    break;

  default:
    return '';
    break;
  }

};



/**
 * @function setStateToolbarAndMenus
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Set the checked state of the toolbar button associated
 *       with the current sidebar, or turn off if no sidebar is
 *       displayed. Also keep the checked state of the menuitem
 *       on the View/Sidebar menu in sync with sidebar display.
 */

OAA_CI_UTILS.setStateToolbarAndMenus = function (window, flag) {

  var toolbarbutton = window.document.getElementById(OAA_CI_UTILS.last_toolbarbutton_id);
  if (toolbarbutton) toolbarbutton.checked = flag;

  var menuitemSidebar = window.document.getElementById('ID_MENU_VIEW_SIDEBAR');
  if (menuitemSidebar) menuitemSidebar.setAttribute('checked', flag);

  var menuitemMain = window.document.getElementById(OAA_CI_UTILS.last_menuitem_id);
  if (menuitemMain) menuitemMain.setAttribute('checked', flag);
 
};

/**
 * @function showWindowLog
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc shows the log information for the last evaluation
 *
 * @param {Object} window - parent window for new window
 * @param {String} format - format of the the log file (valid values: TEXT, XML, JSON and HTML)
 */

OAA_CI_UTILS.showWindowLog = function (window, format) {

  if (OAA_CI_UTILS.oaa_log_window &&
    !OAA_CI_UTILS.oaa_log_window.closed) {
    OAA_CI_UTILS.showLogText();
  }
  else {
    OAA_CI_UTILS.oaa_log_window = window.open("chrome://oaa-cache-inspector/content/oaa-log-window.xul",
                      "oaaLogWindow", "chrome,centerscreen");
    OAA_CI_UTILS.oaa_log_window.onload = function () { OAA_CI_UTILS.showLogText(); };
  }
};

/**
 * @function showLogText
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc updates the log window with the text version of the log
 */

OAA_CI_UTILS.showLogText = function () {

  if (OAA_CI_UTILS.oaa_log_window &&
      OAA_CI_UTILS.oaa_log_window.document) {

    var oaa_log_textbox = OAA_CI_UTILS.oaa_log_window.document.getElementById('ID_OAA_LOG_TEXTBOX');

    if (oaa_log_textbox && OAA_CI_UTILS.log) {
      oaa_log_textbox.value = OAA_CI_UTILS.log.toString();

      OAA_CI_UTILS.checkLogToolbarButton('ID_OAA_LOG_BUTTON_TEXT');
    }
  }
};

/**
 * @function showLogXML
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc updates the log window with the text version of the log
 */

OAA_CI_UTILS.showLogXML = function () {

  if (OAA_CI_UTILS.oaa_log_window &&
      OAA_CI_UTILS.oaa_log_window.document) {

    var oaa_log_textbox = OAA_CI_UTILS.oaa_log_window.document.getElementById('ID_OAA_LOG_TEXTBOX');

    if (oaa_log_textbox && OAA_CI_UTILS.log) {
      oaa_log_textbox.value = OAA_CI_UTILS.log.toXML();

      OAA_CI_UTILS.checkLogToolbarButton('ID_OAA_LOG_BUTTON_XML');
    }
  }
};

/**
 * @function showLogJSON
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc updates the log window with the text version of the log
 */

OAA_CI_UTILS.showLogJSON = function () {

  if (OAA_CI_UTILS.oaa_log_window &&
      OAA_CI_UTILS.oaa_log_window.document) {

    var oaa_log_textbox = OAA_CI_UTILS.oaa_log_window.document.getElementById('ID_OAA_LOG_TEXTBOX');

    if (oaa_log_textbox && OAA_CI_UTILS.log) {
      OAA_CI_UTILS.checkLogToolbarButton('ID_OAA_LOG_BUTTON_JSON');
    }
  }
};

/**
 * @function checkLogToolbarButton
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc updates the log window with the text version of the log
 *
 * @param {String} id - XUL ID of the toolbarbutton to check
 */

OAA_CI_UTILS.checkLogToolbarButton = function (id) {

  var button_text = OAA_CI_UTILS.oaa_log_window.document.getElementById('ID_OAA_LOG_BUTTON_TEXT');
  var button_xml  = OAA_CI_UTILS.oaa_log_window.document.getElementById('ID_OAA_LOG_BUTTON_XML');
  var button_json = OAA_CI_UTILS.oaa_log_window.document.getElementById('ID_OAA_LOG_BUTTON_JSON');

  if (button_text && button_xml && button_json) {

    button_text.checked = false;
    button_xml.checked = false;
    button_json.checked = false;

    switch (id) {

    case 'ID_OAA_LOG_BUTTON_TEXT':
      button_text.checked = true;
      break;

    case 'ID_OAA_LOG_BUTTON_XML':
      button_xml.checked = true;
      break;

    case 'ID_OAA_LOG_BUTTON_JSON':
      button_json.checked = true;
      break;
    }
  }
};

/**
 * @function showResultsText
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc updates the result window with the text version of the result
 */

OAA_CI_UTILS.showResultsText = function () {

  if (OAA_CI_UTILS.oaa_result_window &&
      OAA_CI_UTILS.oaa_result_window.document) {

    var oaa_results_textbox = OAA_CI_UTILS.oaa_result_window.document.getElementById('ID_OAA_RESULTS_TEXTBOX');

    if (oaa_results_textbox && OAA_CI_UTILS.result) {

      oaa_results_textbox.value = OAA_CI_UTILS.result.toString();

      OAA_CI_UTILS.checkResultsToolbarButton("ID_OAA_RESULTS_BUTTON_TEXT");
    }
  }
};

/**
 * @function showResultsXML
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc updates the result window with the text version of the result
 */

OAA_CI_UTILS.showResultsXML = function () {

  if (OAA_CI_UTILS.oaa_result_window &&
      OAA_CI_UTILS.oaa_result_window.document) {

    var oaa_results_textbox = OAA_CI_UTILS.oaa_result_window.document.getElementById('ID_OAA_RESULTS_TEXTBOX');

    if (oaa_results_textbox && OAA_CI_UTILS.result) {
      var xml = OAA_CI_UTILS.result.toXML();
      oaa_results_textbox.maxLength = xml.length;
      oaa_results_textbox.value = xml;

      OAA_CI_UTILS.checkResultsToolbarButton('ID_OAA_RESULTS_BUTTON_XML');
    }
  }
};

/**
 * @function showResultsJSON
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc updates the result window with the text version of the result
 */

OAA_CI_UTILS.showResultsJSON = function () {

  if (OAA_CI_UTILS.oaa_result_window &&
      OAA_CI_UTILS.oaa_result_window.document) {

    var oaa_result_textbox = OAA_CI_UTILS.oaa_result_window.document.getElementById('ID_OAA_RESULTS_TEXTBOX');

    if (oaa_result_textbox && OAA_CI_UTILS.result) {
      var json = OAA_CI_UTILS.result.toDjango();
      oaa_result_textbox.maxLength = json.length;
      oaa_result_textbox.value = json;

      OAA_CI_UTILS.checkResultsToolbarButton('ID_OAA_RESULTS_BUTTON_JSON');

    }
  }
};

/**
 * @function checkResultsToolbarButton
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc updates the result window with the text version of the result
 *
 * @param {String} id - XUL ID of the toolbarbutton to check
 */

OAA_CI_UTILS.checkResultsToolbarButton = function (id) {

  var button_text = OAA_CI_UTILS.oaa_result_window.document.getElementById('ID_OAA_RESULTS_BUTTON_TEXT');
  var button_xml  = OAA_CI_UTILS.oaa_result_window.document.getElementById('ID_OAA_RESULTS_BUTTON_XML');
  var button_json = OAA_CI_UTILS.oaa_result_window.document.getElementById('ID_OAA_RESULTS_BUTTON_JSON');

  if (button_text && button_xml && button_json) {

    button_text.checked = false;
    button_xml.checked  = false;
    button_json.checked = false;

    switch (id) {

    case "ID_OAA_RESULTS_BUTTON_TEXT":
      button_text.checked = true;
      break;

    case 'ID_OAA_RESULTS_BUTTON_XML':
      button_xml.checked = true;
      break;

    case 'ID_OAA_RESULTS_BUTTON_JSON':
      button_json.checked = true;
      break;
    }
  }
};

/* ---------------------------------------------------------------- */
/*                    Generic Utility Functions                     */
/* ---------------------------------------------------------------- */

/**
 * @function showProperty
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Display console message with the value of the specified property of an object.
 *
 * @param {Object} obj - the object of interest
 * @param {String} name - name of property whose value is to be displayed
 */

OAA_CI_UTILS.showProperty = function (obj, name) {
  var prefix = 'PROPERTY INFO for ' + obj + '[' + name + ']: ';
  var info;
  if (typeof obj[name] === 'undefined') info = 'undefined';
  else info = obj[name];
  OAA_CI_UTILS.console(prefix + info);
};

/**
 * @function showProperties
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Display console message listing all properties of an object, excluding methods.
 *
 * @param {Object} obj - the object of interest
 * @param {String} name - (optional) identifier of the object
 * @param {Boolean} unsorted - (optional) if true, do not sort the list alphabetically
 */

OAA_CI_UTILS.showProperties = function (obj, name, unsorted) {
  if (!name) name = obj;
  var prefix = 'PROPERTIES for ' + name + ':\n';
  var properties = [];
  for (var propertyName in obj) {
    if (!(typeof obj[propertyName] === 'function')) properties.push(propertyName);
  }
  if (!unsorted) properties.sort();
  OAA_CI_UTILS.console(prefix + properties.join(', '));
};

/**
 * @function showMethods
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Display console message listing all methods of an object, excluding other properties.
 *
 * @param {Object} obj - the object of interest
 * @param {String} name - (optional) identifier of the object
 * @param {Boolean} unsorted - (optional) if true, do not sort the list alphabetically
 */

OAA_CI_UTILS.showMethods = function (obj, name, unsorted) {
  if (!name) name = obj;
  var prefix = 'METHODS for ' + name + ':\n';
  var methods = [];
  for (var propertyName in obj) {
    if (typeof obj[propertyName] === 'function') methods.push(propertyName);
  }
  if (!unsorted) methods.sort()
  OAA_CI_UTILS.console(prefix + methods.join(', '));
};

/**
 * @function showAttributes
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Display console message listing all attributes of a DOM node.
 *
 * @param {Object} node - the node of interest
 * @param {String} name - (optional) identifier of the object
 * @param {Boolean} unsorted - (optional) if true, do not sort the list alphabetically
 */

OAA_CI_UTILS.showAttributes = function (node, name, unsorted) {
  if (!name) name = node;
  var prefix = 'ATTRIBUTES for ' + name + ':\n';
  var attributes = [];
  for (var attr in node.attributes) {
    attributes.push(attr);
  }
  if (!unsorted) attributes.sort();
  OAA_CI_UTILS.console(prefix + attributes.join(', '));
};
